package com.hht.toolanduilibs.util.usbcamera

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.ImageFormat
import android.hardware.camera2.CameraCaptureSession
import android.hardware.camera2.CameraDevice
import android.hardware.camera2.CameraManager
import android.hardware.camera2.CaptureRequest
import android.media.Image
import android.media.ImageReader
import android.os.*
import android.util.Log
import android.util.Size
import com.hht.toolanduilibs.showLog


/**
 * Author:chen'hu
 * Time:2024/5/30 16:49
 * Description:This is CameraPreviewView
 */

class CameraManagerUtils(context: Context) {

    private val cameraManager: CameraManager =
        context.getSystemService(Context.CAMERA_SERVICE) as CameraManager
    private var curCameraId: String? = null//默认相机id
    private var mPreviewSize = Size(1280, 720)//默认分辨率
    private var curCameraDevice: CameraDevice? = null
    private var mCaptureSession: CameraCaptureSession? = null
    private var mImageReader: ImageReader? = null//预览回调接收者
    private var cameraThread: HandlerThread? = null
    private var cameraHandler: Handler? = null
    private var countNumber = 0//统计次数
    private var mTakePicture = false
    private var mPauseCamera = false
    private var mOnPreviewResultCallBack: OnPreviewResultCallBack? = null

    fun setOnPreviewResultCallBack(callBack: OnPreviewResultCallBack) {
        mOnPreviewResultCallBack = callBack
    }

    private var mHandler: Handler = object : Handler(Looper.getMainLooper()) {
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            ++countNumber
            if (CAMERA_MSG == msg.what) {
                removeMessages(CAMERA_MSG)
                if (countNumber < CAMERA_TIME_NUMBER) {
                    openCamera()
                } else {
                    countNumber = 0
                }
            }
        }
    }

    fun setPauseCamera(pause: Boolean) {
        mPauseCamera = pause
    }

    fun setTakePicture(takePicture: Boolean) {
        mTakePicture = takePicture
    }

    @SuppressLint("MissingPermission")
    private fun openCamera() {
        val cameraIdList = cameraManager.cameraIdList
        if (cameraIdList.isEmpty()) {
            mHandler.apply {
                sendEmptyMessageDelayed(CAMERA_MSG, CAMERA_TIME)
            }
            return
        }
        startCameraThread()
        try {
            mImageReader = ImageReader.newInstance(mPreviewSize.width,
                mPreviewSize.height,
                ImageFormat.YUV_420_888,
                2)
            mImageReader?.let {
                it.setOnImageAvailableListener({ reader ->
                    val yuvData = ImageToYuvHelps.readNV21Data(reader)
                    yuvData?.let { yuvByte ->
                        if (mPauseCamera) {
                            return@setOnImageAvailableListener
                        }
                        val bitmap = ImageToYuvHelps.nv21ToBitmap(yuvByte,
                            mPreviewSize.width,
                            mPreviewSize.height)
                        mOnPreviewResultCallBack?.onPreviewResult(bitmap)
                        if (mTakePicture) {
                            mTakePicture = false
                            mOnPreviewResultCallBack?.onTakePicture(bitmap)
                        }
                    }
                }, cameraHandler)
            }

            if (curCameraId == null) {
                curCameraId = cameraIdList[0]
            }
            cameraManager.openCamera(curCameraId!!, object : CameraDevice.StateCallback() {
                override fun onOpened(camera: CameraDevice) {
                    curCameraDevice = camera
                    createCaptureSession()
                }

                override fun onDisconnected(camera: CameraDevice) {
                    "onDisconnected".showLog(2)
                }

                override fun onError(camera: CameraDevice, error: Int) {
                    "onError,error==$error".showLog(2)
                }
            }, cameraHandler)

        } catch (e: Exception) {
            e.printStackTrace()
        }

    }

    private fun releaseCamera() {
        mHandler.removeMessages(CAMERA_MSG)
        try {
            mCaptureSession?.let {
                it.close()
                null
            }
        } catch (e: Exception) {
            e.printStackTrace()
        } finally {
            curCameraDevice?.let {
                it.close()
                null
            }
            mImageReader?.let {
                it.close()
                null
            }
            stopCameraThread()
        }

    }

    private fun createCaptureSession() {
        curCameraDevice?.let {
            try {
                it.createCaptureSession(listOf(mImageReader!!.surface),
                    object : CameraCaptureSession.StateCallback() {
                        override fun onConfigured(cameraCaptureSession: CameraCaptureSession) {
                            "onConfigured  ${cameraThread?.name}   $mPreviewSize".showLog(3)
                            try {
                                mCaptureSession = cameraCaptureSession
                                val builder: CaptureRequest.Builder =
                                    it.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW)
                                mImageReader?.let { imageReader ->
                                    builder.addTarget(imageReader.surface)
                                }

                                // 设置连续自动对焦和自动曝光
                                builder.set(CaptureRequest.CONTROL_AF_MODE,
                                    CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE)
                                builder.set(CaptureRequest.CONTROL_AE_MODE,
                                    CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH)
                                val captureRequest = builder.build()
                                // 一直发送预览请求
                                mCaptureSession?.setRepeatingRequest(captureRequest,
                                    null,
                                    cameraHandler)
                            } catch (e: Exception) {
                                e.printStackTrace()
                            }
                        }

                        override fun onConfigureFailed(cameraCaptureSession: CameraCaptureSession) {
                        }
                    },
                    cameraHandler)
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

    fun onResume() {
        openCamera()
    }

    fun onPause() {
        releaseCamera()
    }

    fun switchCamera() {
        releaseCamera()
        SystemClock.sleep(100)
        curCameraId = if (curCameraId == null) {
            cameraManager.cameraIdList[0]
        } else {
            val nextCameraId =
                getNextCameraId(cameraManager.cameraIdList.toList(), curCameraId) ?: return
            nextCameraId
        }
        openCamera()

    }

    private fun getNextCameraId(
        cameraIdList: List<String>,
        cameraId: String?,
    ): String? {
        if (cameraIdList.isEmpty()) {
            return null
        }
        if (!cameraIdList.contains(cameraId)) {
            return cameraIdList[0]
        }
        val index = cameraIdList.indexOf(cameraId)
        var nextIndex = index + 1
        if (nextIndex == cameraIdList.size) {
            nextIndex = 0
        }
        return cameraIdList[nextIndex]
    }

    private fun startCameraThread() {
        cameraThread = HandlerThread(THREAD_NAME)
        cameraThread?.start()
        cameraHandler = Handler(cameraThread!!.looper)
    }

    private fun stopCameraThread() {
        cameraHandler?.removeCallbacksAndMessages(null)
        cameraHandler = null
        cameraThread?.let {
            it.quitSafely()
            it.join()
            null
        }
    }

    companion object {
        private const val THREAD_NAME = "camera_thread"
        private const val CAMERA_MSG = 110
        private const val CAMERA_TIME = 1 * 1000L
        private const val CAMERA_TIME_NUMBER = 2
    }

    interface OnPreviewResultCallBack {
        fun onPreviewResult(bitmap: Bitmap)
        fun onTakePicture(bitmap: Bitmap)
    }
}